///////////////////////////////////////////////////////////////////////////
//
// Spring Engine Source File.
// Copyright (C), Dengtao 2011-2021
// ----------------------------------------------------------------------
// File name:   SfSharedSingleton.h
// Version:     v1.0.0
// Created:     2013/06/14 11:35 by dengtao
// Compilers:   Visual Studio 2008
// Description: 
// ----------------------------------------------------------------------
// History:
//
///////////////////////////////////////////////////////////////////////////

#ifndef _SfSharedSingleton_H_
#define _SfSharedSingleton_H_

#include "SfBaseDefines.h"

namespace Sunflower
{

//////////////////////////////////////////////////////////////////////////
//Summary:
//	template class of Shared Singleton.
//////////////////////////////////////////////////////////////////////////
template <class T>
class SharedSingleton
{
public:
	//
	//Summary:
	//	get instance.
	static T* GetInstancePtr();
	static T& GetInstance();

protected:
	static T* ms_Instance;

public:
	//
	//Summary:
	//	constructor.
	SharedSingleton();

	//
	//Summary:
	//	constructor.
	~SharedSingleton();
};

//////////////////////////////////////////////////////////////////////////
// begin implement SharedSingleton

template <class T>
T* SharedSingleton<T>::ms_Instance = SfNull;

//
//Summary:
//	get instance.
template <class T>
T* SharedSingleton<T>::GetInstancePtr()
{
	return ms_Instance;
}

template <class T>
T& SharedSingleton<T>::GetInstance()
{
	SfAssertValidPtr(ms_Instance);
	return *ms_Instance;
}

//
//Summary:
//	constructor.
template <class T>
SharedSingleton<T>::SharedSingleton()
{
	SfAssertNullPtr(ms_Instance);
	ms_Instance = (T*)this;
}

//
//Summary:
//	virtual constructor.
template <class T>
SharedSingleton<T>::~SharedSingleton()
{
	SfAssertValidPtr(ms_Instance);
	ms_Instance = SfNull;
}

// end implement SharedSingleton
//////////////////////////////////////////////////////////////////////////

#define SfCreateSharedSingleton(T) \
	SfNew T()

#define SfDetroySharedSingleton(T) \
	if (SfIsValidPtr(T::GetInstancePtr()))\
	{\
		SfDelete T::GetInstancePtr();\
	}

} // end of namespace Sunflower
#endif
